package de.htw.ejb.manager;

import java.util.List;

import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptors;
import javax.interceptor.InvocationContext;
import javax.persistence.EntityExistsException;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;
import javax.persistence.RollbackException;

import de.htw.ejb.manager.exceptions.EntityManagementDienstException;
import de.htw.ejb.manager.listener.EntityManagementDientLifeCycleMonitor;
import de.htw.ejb.model.Artikel;
import de.htw.ejb.model.Bestellung;
import de.htw.ejb.model.Kunde;
import de.htw.ejb.model.Pizza;

@Stateless
@TransactionManagement( TransactionManagementType.CONTAINER )
@TransactionAttribute( TransactionAttributeType.REQUIRED )
@Interceptors( value = { EntityManagementDientLifeCycleMonitor.class } )
public class EntityManagementDienstBean implements EntityManagementDienstLocal,
		EntityManagementDienstRemote
{
	
	@PersistenceContext( unitName = "MySQL" )
	EntityManager	em;
	
	public void speichern( Object object ) throws EntityManagementDienstException
	{
		try
		{
			em.persist( object );
		}
		catch ( EntityExistsException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( PersistenceException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( Exception e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
	}
	
	@SuppressWarnings( "unchecked" )
	public List<Artikel> sucheArtikelPerBezeichnung( String bezeichnung )
			throws EntityManagementDienstException
	{
		List<Artikel> artikel = null;
		
		try
		{
			artikel = em.createQuery( Artikel.SELECT_BY_BEZEICHNUNG )
					.setParameter( Artikel.BEZEICHNUNG, bezeichnung ).getResultList();
		}
		catch ( EntityNotFoundException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( NonUniqueResultException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( NoResultException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( PersistenceException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( Exception e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		
		return artikel;
	}
	
	@SuppressWarnings( "unchecked" )
	public List<Artikel> sucheArtikelPerArtikelnummer( int artikelnummer )
			throws EntityManagementDienstException
	{
		List<Artikel> artikel = null;
		
		try
		{
			artikel = em.createQuery( Artikel.SELECT_BY_ARTIKELNUMMER )
					.setParameter( Artikel.ARTIKELNUMMER, artikelnummer ).getResultList();
		}
		catch ( EntityNotFoundException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( NonUniqueResultException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( NoResultException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( PersistenceException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( Exception e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		
		return artikel;
	}
	
	@SuppressWarnings( "unchecked" )
	public List<Bestellung> sucheBestellungPerBestellnummer( int bestellnummer )
			throws EntityManagementDienstException
	{
		List<Bestellung> bestellungen = null;
		
		try
		{
			bestellungen = em.createQuery( Bestellung.SELECT_BY_ID )
					.setParameter( Bestellung.ID, bestellnummer ).getResultList();
		}
		catch ( EntityNotFoundException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( NonUniqueResultException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( NoResultException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( PersistenceException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( Exception e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		
		return bestellungen;
	}
	
	@SuppressWarnings( "unchecked" )
	public List<Kunde> sucheKundePerName( String name )
			throws EntityManagementDienstException
	{
		List<Kunde> kunden = null;
		
		try
		{
			kunden = em.createQuery( Kunde.SELECT_BY_NAME )
					.setParameter( Kunde.NAME, name ).getResultList();
		}
		catch ( EntityNotFoundException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( NonUniqueResultException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( NoResultException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( PersistenceException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( Exception e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		
		return kunden;
	}
	
	@SuppressWarnings( "unchecked" )
	public List<Kunde> sucheKundePerKundennummer( int kundennummer )
			throws EntityManagementDienstException
	{
		List<Kunde> kunden = null;
		
		try
		{
			kunden = em.createQuery( Kunde.SELECT_BY_ID )
					.setParameter( Kunde.ID, kundennummer ).getResultList();
		}
		catch ( EntityNotFoundException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( NonUniqueResultException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( NoResultException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( PersistenceException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( Exception e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		
		return kunden;
	}
	
	@SuppressWarnings( "unchecked" )
	public List<Pizza> suchePizzaPerBezeichnung( String bezeichnung )
			throws EntityManagementDienstException
	{
		List<Pizza> pizzen = null;
		
		try
		{
			pizzen = em.createQuery( Pizza.SELECT_BY_BEZEICHNUNG )
					.setParameter( Kunde.NAME, bezeichnung ).getResultList();
		}
		catch ( NonUniqueResultException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( NoResultException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( PersistenceException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( Exception e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		
		return pizzen;
	}
	
	@SuppressWarnings( "unchecked" )
	public List<Pizza> suchePizzaPerArtikelnummer( int artikelnummer )
			throws EntityManagementDienstException
	{
		List<Pizza> pizzen = null;
		
		try
		{
			pizzen = em.createQuery( Pizza.SELECT_BY_ID )
					.setParameter( Pizza.ID, artikelnummer ).getResultList();
		}
		catch ( NonUniqueResultException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( NoResultException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( PersistenceException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( Exception e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		
		return pizzen;
	}
	
	public void loeschenArtikel( int id ) throws EntityManagementDienstException
	{
		try
		{
			Artikel artikel = em.find( Artikel.class, id );
			em.remove( artikel );
		}
		catch ( EntityNotFoundException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( PersistenceException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( Exception e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
	}
	
	public void loescheArtikel( int artikelnummer )
			throws EntityManagementDienstException
	{
		try
		{
			em.getTransaction().begin();
			Artikel artikel = em.find( Artikel.class, artikelnummer );
			em.remove( artikel );
			em.getTransaction().commit();
		}
		catch ( EntityNotFoundException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( OptimisticLockException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( RollbackException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( PersistenceException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( Exception e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
	}
	
	public void loescheBestellung( int bestellnummer )
			throws EntityManagementDienstException
	{
		try
		{
			em.getTransaction().begin();
			Bestellung bestellung = em.find( Bestellung.class, bestellnummer );
			em.remove( bestellung );
			em.getTransaction().commit();
		}
		catch ( EntityNotFoundException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( OptimisticLockException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( RollbackException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( PersistenceException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( Exception e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
	}
	
	public void loescheKunde( int kundennummer )
			throws EntityManagementDienstException
	{
		try
		{
			em.getTransaction().begin();
			Kunde kunde = em.find( Kunde.class, kundennummer );
			em.remove( kunde );
			em.getTransaction().commit();
		}
		catch ( EntityNotFoundException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( OptimisticLockException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( RollbackException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( PersistenceException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( Exception e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
	}
	
	public void loeschePizza( int artikelnummer )
			throws EntityManagementDienstException
	{
		try
		{
			em.getTransaction().begin();
			Pizza pizza = em.find( Pizza.class, artikelnummer );
			em.remove( pizza );
			em.getTransaction().commit();
		}
		catch ( EntityNotFoundException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( OptimisticLockException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( RollbackException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( PersistenceException e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
		catch ( Exception e )
		{
			throw new EntityManagementDienstException( e.getMessage(), e.getCause() );
		}
	}
	
	/**
	 * Ueberwacht Methodenaufrufe.
	 * 
	 * @param ic
	 * 
	 * @return weitere Interceptoren, Kernmethode
	 * 
	 * @throws EntityManagementDienstException
	 */
	@AroundInvoke
	public Object abfangen( InvocationContext ic )
			throws EntityManagementDienstException
	{
		try
		{
			System.out.println( ic.getMethod().getName() + "() wird aufgerufen" );
			return ic.proceed();
		}
		catch ( Exception e )
		{
			throw new EntityManagementDienstException( e );
		}
	}
}
